package com.bestcem.xm.qdes.grpc.client;

import cn.hutool.core.util.StrUtil;
import com.bestcem.bp.xm.user.grpc.v1.services.*;
import com.bestcem.xm.common.core.constant.GrpcClientNames;
import com.bestcem.xm.component.cache.annotation.XmCache;
import com.bestcem.xm.qdes.convert.grpc.QdesGrpcConvertMapper;
import com.bestcem.xm.qdes.grpc.client.dto.OrgInfoDto;
import com.bestcem.xm.qdes.grpc.client.dto.UserDto;
import com.zy.dp.proto.base.v1.Code;
import io.grpc.StatusRuntimeException;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.bestcem.bp.grpc.v1.base.Code.ERROR;

@Slf4j
@Component
public class UserGrpcClient {

    @GrpcClient(GrpcClientNames.DS_USER)
    private UserServiceGrpc.UserServiceBlockingStub userServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private OrgServiceGrpc.OrgServiceBlockingStub orgServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private UserGroupServiceGrpc.UserGroupServiceBlockingStub userGroupServiceBlockingStub;

    private final com.bestcem.xm.qdes.convert.grpc.QdesGrpcConvertMapper grpcConvertMapper;

    public UserGrpcClient(QdesGrpcConvertMapper grpcConvertMapper) {
        this.grpcConvertMapper = grpcConvertMapper;
    }

    @XmCache
    public UserDto getUser(String userId) {
        GetUserByIdRequest.Builder builder = GetUserByIdRequest.newBuilder();
        builder.setId(userId);
        try {
            GetUserByIdResponse response = userServiceBlockingStub.getUserById(builder.build());
            if (Objects.isNull(response) || response.getStatus().getCodeValue() != 0) {
                log.error("[qdes] USER getUser {} Error; ErrorMsg: {}", userId, response);
                return null;
            }
            return responseToUserDTO(response);
        } catch (Exception e) {
            log.error("[qdes] USER getUser {} Error; ErrorMsg: {}", userId, e.getMessage(), e);
            return null;
        }
    }

    private UserDto responseToUserDTO(com.bestcem.bp.xm.user.grpc.v1.services.GetUserByIdResponse response) {
        com.bestcem.bp.xm.user.grpc.v1.services.User user = response.getUser();
        return grpcConvertMapper.toUserDto(user);
    }

    public List<String> listOrgAdminIds(String orgId) {
        ListAdminsByOrgIdsRequest request = ListAdminsByOrgIdsRequest.newBuilder()
                .addAllOrgIds(Collections.singletonList(orgId))
                .build();
        ListAdminsByOrgIdsResponse response;
        try {
            response = userServiceBlockingStub.listAdminsByOrgIds(request);
            if (response.getStatus().getCodeValue() != 0) {
                log.error("[Qdes]根据组织id获取该公司下对应的权限id失败，response:{}", response);
                return Collections.emptyList();
            }
        } catch (StatusRuntimeException e) {
            log.error("[Qdes]根据组织id获取该公司下对应的权限id失败，request:{}", request, e);
            return Collections.emptyList();
        }

        List<User> users = response.getUsersList();
        if (CollectionUtils.isEmpty(users)) {
            return Collections.emptyList();
        }
        return users.stream().map(User::getId).collect(Collectors.toList());

    }

    public List<UserDto> listUserByUserIds(List<String> userIds) {
        ListUsersByIdsRequest.Builder builder = ListUsersByIdsRequest.newBuilder();
        builder.addAllIds(userIds);
        try {
            ListUsersByIdsResponse response = userServiceBlockingStub.listUsersByIds(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[QDES] USER listUserByUserIds {} Error; ErrorMsg: {}", userIds, response);
                return new ArrayList<>();
            }
            return grpcConvertMapper.toUserDtoList(response.getUsersList());
        } catch (Exception e) {
            log.error("[QDES] USER listUserByUserIds {} Error", userIds, e);
            return new ArrayList<>();
        }
    }

    public OrgInfoDto getOrganization(String orgId) {
        GetOrgByIdOrCodeRequest.Builder builder = GetOrgByIdOrCodeRequest.newBuilder();
        builder.setId(orgId);
        try {
            GetOrgByIdOrCodeResponse response = orgServiceBlockingStub.getOrgByIdOrCode(builder.buildPartial());
            if (Objects.isNull(response) || response.getStatus().getCodeValue() != 0) {
                log.error("[qdes] USER getOrganization {} Error; ErrorMsg: {}", orgId, response);
                return null;
            }
            Organization organization = response.getOrg();
            OrgInfoDto orgInfoDTO = new OrgInfoDto();
            orgInfoDTO.setId(organization.getId());
            orgInfoDTO.setIndustryId(organization.getIndustryId());
            orgInfoDTO.setIsDeliverCheck(organization.getDeliverAudit());
            orgInfoDTO.setSkin(organization.getSkin());
            orgInfoDTO.setCode(organization.getCode());
            orgInfoDTO.setComplete(organization.getComplete());
            return orgInfoDTO;
            //return grpcConvertMapper.toOrgInfoDto(response.getOrg());
        } catch (Exception e) {
            log.error("[qdes] USER getOrganization {} Error; ErrorMsg: {}", orgId, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 根据user_id 获取 祖先层级 ids
     *
     * @param userId 用户id
     * @return 祖先层级id列表
     */
    @Nullable
    public List<String> listAncestorIdsByUserId(String userId) {
        ListAncestorGroupIdsByUidRequest.Builder builder = ListAncestorGroupIdsByUidRequest.newBuilder();
        if (StrUtil.isEmpty(userId)) {
            return Collections.emptyList();
        }
        builder.setUserId(userId);
        try {
            ListAncestorGroupIdsByUidResponse response = userGroupServiceBlockingStub.listAncestorGroupIdsByUid(builder.build());
            if (Objects.isNull(response) || response.getStatus().getCodeValue() != 0) {
                log.error("[QDE] USER listAncestorIdsByUserId {} Error; ErrorMsg: {}", userId, response);
                return new ArrayList<>();
            }
            return response.getIdsList();
        } catch (Exception e) {
            log.error("[QDE] USER listAncestorIdsByUserId {} Error; ErrorMsg: {}", userId, e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    public boolean checkCurrentChecker(String userId, String orgId) {
        CheckAuditorPermissionRequest.Builder builder = CheckAuditorPermissionRequest.newBuilder();
        if (StrUtil.isEmpty(userId) || StrUtil.isEmpty(orgId)) {
            return false;
        }
        builder.setUserId(userId);
        builder.setOrgId(orgId);
        try {
            CheckAuditorPermissionResponse response = userServiceBlockingStub.checkAuditorPermission(builder.build());
            if (Objects.isNull(response) || response.getStatus().getCodeValue() != 0) {
                log.error("[QDE] USER checkAuditorPermission {} Error; ErrorMsg: {}", userId, response);
                return false;
            }
            return response.getAuditor();
        } catch (Exception e) {
            log.error("[QDE] USER checkAuditorPermission {} Error; ErrorMsg: {}", userId, e.getMessage(), e);
            return false;
        }
    }


    /**
     * 根据公司id获取管理员
     *
     * @param orgId
     * @return com.bestcem.bp.xm.user.grpc.v1.services.User
     * @author zhangfeng <feng.zhang@idiaoyan.com>
     * @date 2022/6/15 17:45
     */
    public User getAdminUserByOrgId(String orgId) {
        ListAdminsRequest.Builder builder = ListAdminsRequest.newBuilder();
        builder.setOrgId(orgId);
        try {
            ListAdminsResponse response = userServiceBlockingStub.listAdmins(builder.build());
            if (Code.OK_VALUE == response.getStatus().getCodeValue() && response.getUsersCount() > 0) {
                return response.getUsers(0);
            }
        } catch (Exception e) {
            log.error("[qdes] 调用user接口listAdmins失败 orgId:{} ", orgId, e);
        }
        return null;
    }

    /**
     * 获取高级管理员
     *
     * @param orgId orgId
     * @return User info
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/11/4 20:30
     */
    public List<String> getSeniorAdminIdByOrgId(String orgId) {
        ListSeniorAdminIdsRequest.Builder builder = ListSeniorAdminIdsRequest.newBuilder();
        builder.setOrgId(orgId);
        try {
            ListSeniorAdminIdsResponse response = userServiceBlockingStub.listSeniorAdminIds(builder.build());
            if (Code.OK_VALUE == response.getStatus().getCodeValue() && !ObjectUtils.isEmpty(response.getIdsList())) {
                return response.getIdsList();
            }
        } catch (Exception e) {
            log.error("[qdes] 调用user接口listSeniorAdminIds失败 orgId:{} ", orgId, e);
        }
        return null;
    }

}
